package jnpf.ureport.utils;

import jnpf.ureport.build.Context;
import jnpf.ureport.definition.value.DatasetValue;
import jnpf.ureport.definition.value.Value;
import jnpf.ureport.model.Cell;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;


public class DataUtils {

    public static List<Map<String, Object>> fetchData(Cell cell, Context context, String datasetName) {
        Cell leftCell = fetchLeftCell(cell, context, datasetName);
        Cell topCell = fetchTopCell(cell, context, datasetName);
        List<Map<String, Object>> leftList = null;
        List<Map<String, Object>> topList = null;
        if (leftCell != null) {
            leftList = leftCell.getBindData();
        }
        if (topCell != null) {
            topList = topCell.getBindData();
        }
        if (leftList == null && topList == null) {
            List<Map<String, Object>> data = context.getDatasetData(datasetName);
            return data;
        } else if (leftList == null) {
            return topList;
        } else if (topList == null) {
            return leftList;
        } else {
            String leftProp = ((DatasetValue) leftCell.getValue()).getProperty();
            Object leftValue = leftCell.getData();
            String topProp = ((DatasetValue) topCell.getValue()).getProperty();
            Object topValue = topCell.getData();
            List<Map<String, Object>> topDataList = new ArrayList<>();
            for (Map<String, Object> data : topList) {
                if (Objects.equals(data.get(leftProp), leftValue)) {
                    topDataList.add(data);
                }
            }
            List<Map<String, Object>> leftDataList = new ArrayList<>();
            for (Map<String, Object> data : leftList) {
                if (Objects.equals(data.get(topProp), topValue)) {
                    leftDataList.add(data);
                }
            }
            List<Map<String, Object>> result = leftDataList.size() > topDataList.size() ? topDataList : leftDataList;
            return result;
        }
    }

    public static Cell fetchLeftCell(Cell cell, Context context, String datasetName) {
        Cell targetCell = null;
        Cell parentCell = cell.getLeftParentCell();
        if (parentCell != null) {
            Value cellValue = parentCell.getValue();
            if (cellValue instanceof DatasetValue) {
                DatasetValue datasetValue = (DatasetValue) cellValue;
                if (datasetValue != null) {
                    String dataName = datasetValue.getDatasetName();
                    if (Objects.equals(dataName, datasetName)) {
                        if (parentCell.getBindData() != null) {
                            targetCell = parentCell;
                        }
                    }
                }
            }
        }
        return targetCell;
    }

    public static Cell fetchTopCell(Cell cell, Context context, String datasetName) {
        Cell targetCell = null;
        Cell parentCell = cell.getTopParentCell();
        if (parentCell != null) {
            Value cellValue = parentCell.getValue();
            if (cellValue instanceof DatasetValue) {
                DatasetValue datasetValue = (DatasetValue) cellValue;
                if (datasetValue != null) {
                    String dataName = datasetValue.getDatasetName();
                    if (Objects.equals(dataName, datasetName)) {
                        if (parentCell.getBindData() != null) {
                            targetCell = parentCell;
                        }
                    }
                }
            }
        }
        return targetCell;
    }

    private static void leftList(Cell cell, List<Cell> list) {
        if (cell != null) {
            list.add(cell);
            leftList(cell.getLeftParentCell(), list);
        }
    }

    private static void topList(Cell cell, List<Cell> list) {
        if (cell != null) {
            list.add(cell);
            topList(cell.getTopParentCell(), list);
        }
    }

    public static void cellList(Cell cell, boolean left, boolean top) {
        if (cell != null) {
            if (left && cell.getLeftParentCell() != null) {
                List<Cell> leftList = new ArrayList<>();
                leftList(cell.getLeftParentCell(), leftList);
                cell.setLeftParentList(leftList);
            }
            if (top && cell.getTopParentCell() != null) {
                List<Cell> topList = new ArrayList<>();
                topList(cell.getTopParentCell(), topList);
                cell.setTopParentList(topList);
            }
        }
    }

    public static List<BigDecimal> dataList(DatasetValue expr, List<Map<String, Object>> objList) {
        List<BigDecimal> result = new ArrayList<>();
        String property = expr.getProperty();
        for (Map<String, Object> o : objList) {
            Object data = o.get(property);
            try {
                BigDecimal bigDecimal = new BigDecimal(String.valueOf(data));
                result.add(bigDecimal);
            } catch (Exception e) {
            }
        }
        return result;
    }

}
